package com.booksmanager.aspect;

import com.booksmanager.annotation.Log;
import com.booksmanager.pojo.Option;
import com.booksmanager.service.OptionService;
import com.booksmanager.utils.HttpContextUtils;
import com.booksmanager.utils.IPUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * @ Author     ：Yan
 * @ Date       ：Created in 19:52 2020/5/22
 * @ Description：
 * @ Modified By：
 * @Version: $
 */
@Aspect
@Component
public class LogAspect {
    @Autowired
    private OptionService optionService;

    @Pointcut("@annotation(com.booksmanager.annotation.Log)")
    public void pointcut(){}

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint point){
        Object result=null;
        long beginTime = System.currentTimeMillis();
        try {
            result=point.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        long time=System.currentTimeMillis()-beginTime;

        saveLog(point,time);
        return result;
    }

    /**
     * 保存日志
     * @param joinPoint
     * @param time
     */
    private void saveLog(ProceedingJoinPoint joinPoint,long time){
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        Method method=signature.getMethod();
        Option option = new Option();
        Log logAnnotation = method.getAnnotation(Log.class);
        if(logAnnotation!=null){
            option.setOperation(logAnnotation.value());
        }

        String className=joinPoint.getTarget().getClass().getName();
        String methodName=signature.getName();
        option.setMethod(className+"."+methodName+"()");

        Object[] args = joinPoint.getArgs();

        LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
        String[] parameterNames = u.getParameterNames(method);
        if(args!=null&&parameterNames!=null){
            String params="";
            for (int i=0;i<args.length;i++){
                params+= "  " + parameterNames[i] + ": " + args[i];
            }
            option.setParams(params);
        }

        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();

        option.setIp(IPUtils.getIpAddr(request));

        String username="测试人员";
        option.setUsername(username);
        option.setTime((int) time);

        option.setCreatetime(new Date());
        optionService.save(option);
    }
}
